﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;

namespace SoGame.Model
{
    /// <summary>
    /// 
    /// </summary>
    public partial class SoGameDbContext : DbContext
    {
        /// <summary>
        /// Gets all game plays.
        /// </summary>
        /// <returns></returns>
        public IQueryable<GamePlay> GetAllGamePlays() {
            return this.GamePlays;
        }

        /// <summary>
        /// Gets the top10 game play.
        /// </summary>
        /// <param name="game">The game.</param>
        /// <returns></returns>
        public IQueryable<GamePlay> GetTop10Score(string game) {
            //return this.GamePlays.Where(g => g.Game == game).OrderByDescending(g => g.Score).Take(10);

            var maxGamePlays =
                from g in GamePlays
                group g by new { g.Game, g.PlayerID } into g
                //let maxScore = g.Max(x => x.Score)
                let gamePlay = g.FirstOrDefault(x => x.Score == g.Max(s => s.Score))
                where gamePlay.Game == game
                orderby gamePlay.Score descending
                select gamePlay;

            return maxGamePlays.Take(10);
        }

        /// <summary>
        /// Saves the game play.
        /// </summary>
        /// <param name="gameplay">The gameplay.</param>
        /// <returns></returns>
        public bool SaveGamePlay(GamePlay gameplay) {
            this.GamePlays.Add(gameplay);
            return this.SaveChanges() > 0;
        }

        /// <summary>
        /// Gets the game play.
        /// </summary>
        /// <param name="gamePlayId">The game play id.</param>
        /// <returns></returns>
        public GamePlay GetGamePlay(int gamePlayId) {
            return this.GamePlays.SingleOrDefault(g => g.ID == gamePlayId);
        }

        /// <summary>
        /// Deletes the game play.
        /// </summary>
        /// <param name="gamePlayId">The game play id.</param>
        public void DeleteGamePlay(int gamePlayId) {
            var gamePlay = this.GamePlays.SingleOrDefault(g => g.ID == gamePlayId);
            if (gamePlayId != null) {
                this.GamePlays.Remove(gamePlay);
                this.SaveChanges();
            }
        }

        /// <summary>
        /// Updates the game play.
        /// </summary>
        /// <param name="gamePlay">The game play.</param>
        public void UpdateGamePlay(GamePlay gamePlay) {
            this.Entry(gamePlay).State = System.Data.EntityState.Modified;
            this.SaveChanges();
        }

        /// <summary>
        /// Determines whether the specified gamePlay has the best score.
        /// </summary>
        /// <param name="gamePlay">The game play.</param>
        /// <returns>
        ///   <c>true</c> if the specified game play has best score; otherwise, <c>false</c>.
        /// </returns>
        public bool IsBestScore(GamePlay gamePlay) {
            var bs = from gp in this.GamePlays
                     where gp.PlayerID.HasValue
                        && gp.Game == gamePlay.Game
                        && gp.Score > gamePlay.Score
                     select gp;

            return !bs.Any();
        }

        /// <summary>
        /// Gets the game plays without player.
        /// </summary>
        /// <returns></returns>
        public IQueryable<GamePlay> GetGamePlaysWithoutPlayer() {
            return this.GamePlays.Where(g => g.Player == null);
        }
    }
}
